package com.liu.yuoj.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.liu.yuoj.annotation.AuthCheck;
import com.liu.yuoj.common.BaseResponse;
import com.liu.yuoj.common.DeleteRequest;
import com.liu.yuoj.common.ErrorCode;
import com.liu.yuoj.common.ResultUtils;
import com.liu.yuoj.constant.UserConstant;
import com.liu.yuoj.exception.BusinessException;
import com.liu.yuoj.exception.ThrowUtils;
import com.liu.yuoj.model.dto.question.*;
import com.liu.yuoj.model.entity.Question;
import com.liu.yuoj.model.entity.User;
import com.liu.yuoj.model.vo.QuestionVO;
import com.liu.yuoj.service.QuestionService;
import com.liu.yuoj.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户接口
 *
 */
@RestController
@RequestMapping("/question")
@Slf4j
public class QuestionController {

    @Resource
    private UserService userService;

    public static final Gson GSON = new Gson();

    @Resource
    private QuestionService questionService;

    // region crud

    /**
     * 创建题目（admin）
     *
     * @param questionAddRequest
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest,HttpServletRequest request) {
        //校验参数
        if (questionAddRequest == null) {
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        //插入数据
        Question question = new Question ();
        BeanUtils.copyProperties (questionAddRequest, question);
        List<String> tags = questionAddRequest.getTags ();
        List<JudgeCase> judgeCase = questionAddRequest.getJudgeCase ();
        JudgeConfig judgeConfig = questionAddRequest.getJudgeConfig ();
        //数据转换
        if (CollUtil.isNotEmpty (tags)){
            question.setTags (GSON.toJson (tags));
        }
        if (CollUtil.isNotEmpty (judgeCase)){
            question.setJudgeCase (GSON.toJson (judgeCase));
        }
        if (judgeConfig != null){
            question.setJudgeConfig (GSON.toJson (judgeConfig));
        }
        //校验参数
        questionService.valid(question,true);
        //获取当前登录用户
        User loginUser = userService.getLoginUser (request);
        question.setUserId (loginUser.getId());
        //保存数据
        boolean save = questionService.save (question);
        ThrowUtils.throwIf (!save,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success (question.getId ());
    }
        /**
         * 删除
         *
         * @param deleteRequest
         * @param request
         * @return
         */
        @PostMapping("/delete")
        public BaseResponse<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
            if (deleteRequest == null || deleteRequest.getId() <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            long id = deleteRequest.getId();
            //鉴权
            validRole (request,deleteRequest.getId ());
            boolean b = questionService.removeById(id);
            return ResultUtils.success(b);
        }

        /**
         * 更新（仅管理员）
         *
         * @param questionUpdateRequest
         * @return
         */
        @PostMapping("/update")
        @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
        public BaseResponse<Boolean> updateQuestion(@RequestBody QuestionUpdateRequest questionUpdateRequest) {
            //校验参数
            Question question = validAndGetQuestion (questionUpdateRequest);
            long id = questionUpdateRequest.getId();
            // 判断是否存在
            Question oldQuestion = questionService.getById(id);
            ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
            boolean result = questionService.updateById(question);
            return ResultUtils.success(result);
        }

        /**
         * 根据 id 获取
         *
         * @param id
         * @return
         */
        @GetMapping("/get/vo")
        public BaseResponse<QuestionVO> getQuestionVOById(@RequestParam long id) {
            if (id <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            //判断题目是否存在
            Question question = questionService.getById(id);
            if (question == null) {
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            }
            return ResultUtils.success(questionService.getQuestionVO(question));
        }

//        ------------获取列表服务接口
        /**
         * 分页获取列表（封装类）
         *
         * @param questionQueryRequest
          * @return
         */
        @PostMapping("/list/page/vo")
        public BaseResponse<Page<QuestionVO>> listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
            //当前页
            long current = questionQueryRequest.getCurrent();
            //页面大小
            long size = questionQueryRequest.getPageSize();
            // 限制爬虫
            ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
            Page<Question> questionPage = questionService.page(new Page<>(current, size),
                    questionService.getQueryWrapper(questionQueryRequest));
            return ResultUtils.success(questionService.getQuestionVOPage(questionPage));
        }

        /**
         * 分页获取当前用户创建的资源列表
         *
         * @param questionQueryRequest
          * @return
         */
        @PostMapping("/my/list/page/vo")
        public BaseResponse<Page<QuestionVO>> listMyQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
                                                                     HttpServletRequest request) {
            if (questionQueryRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            User loginUser = userService.getLoginUser(request);
            questionQueryRequest.setUserId(loginUser.getId());
            long current = questionQueryRequest.getCurrent();
            long size = questionQueryRequest.getPageSize();
            // 限制爬虫
            ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
            Page<Question> questionPage = questionService.page(new Page<>(current, size),
                    questionService.getQueryWrapper(questionQueryRequest));
            return ResultUtils.success(questionService.getQuestionVOPage(questionPage));
        }

        /**
         * 分页获取题目列表（仅管理员）
         *
         * @param questionQueryRequest
         * @return
         */
        @PostMapping("/list/page")
        @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
        public BaseResponse<Page<Question>> listQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest) {
            long current = questionQueryRequest.getCurrent();
            long size = questionQueryRequest.getPageSize();
            Page<Question> questionPage = questionService.page(new Page<>(current, size),
                    questionService.getQueryWrapper(questionQueryRequest));
            return ResultUtils.success(questionPage);
        }

        // endregion

        /**
         * 编辑（用户）
         *
         * @param questionEditRequest
         * @param request
         */
        @PostMapping("/edit")
        public BaseResponse<Boolean> editQuestion(@RequestBody QuestionUpdateRequest questionEditRequest, HttpServletRequest request) {
            Question question = validAndGetQuestion (questionEditRequest);
            //鉴权
            validRole (request,question.getId ());
            boolean result = questionService.updateById(question);
            return ResultUtils.success(result);
        }


        //校验参数
        public Question validAndGetQuestion(QuestionUpdateRequest updateRequest) {
            if (updateRequest == null || updateRequest.getId() <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            Question question = new Question();
            BeanUtils.copyProperties(updateRequest, question);
            List<String> tags = updateRequest.getTags();
            if (tags != null) {
                question.setTags(GSON.toJson(tags));
            }
            List<JudgeCase> judgeCase = updateRequest.getJudgeCase();
            if (judgeCase != null) {
                question.setJudgeCase(GSON.toJson(judgeCase));
            }
            JudgeConfig judgeConfig = updateRequest.getJudgeConfig();
            if (judgeConfig != null) {
                question.setJudgeConfig(GSON.toJson(judgeConfig));
            }
            // 参数校验
            questionService.valid(question, false);

            return question;

        }

        //鉴权
    public void validRole(HttpServletRequest request,Long questionId){
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        Question oldQuestion = questionService.getById(questionId);
        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可编辑
        if (!oldQuestion.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
    }

    }



